home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / dos-grx.c < prev    next >
C/C++ Source or Header  |  1996-06-14  |  20KB  |  825 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * DOS GRX lib svga interface.
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   * (c) 1996 Gustavo Goedert
  8.   */
  9.  
  10. #include "sysconfig.h"
  11. #include "sysdeps.h"
  12.  
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <stdio.h>
  16. #include <assert.h>
  17. #include <signal.h>
  18. #include <unistd.h>
  19. #include <grx20.h>
  20. #include <pc.h>
  21. #include <go32.h>
  22. #include <dpmi.h>
  23. #include <sys/nearptr.h>
  24. #include <sys/exceptn.h>
  25. #include <conio.h>
  26.  
  27. #include "config.h"
  28. #include "options.h"
  29. #include "memory.h"
  30. #include "custom.h"
  31. #include "newcpu.h"
  32. #include "keyboard.h"
  33. #include "xwin.h"
  34. #include "keybuf.h"
  35. #include "disk.h"
  36.  
  37. int CorrectAspectRatio = 0;
  38.  
  39. void my_kbd_handler(void);
  40. void my_mouse_handler(_go32_dpmi_registers *mouse_regs);
  41. void HandleDisk(int num);
  42.  
  43. extern struct _GR_driverInfo _GrDriverInfo;
  44. extern struct _GR_contextInfo _GrContextInfo;
  45.  
  46. #define BANKPOS(offs)   ((unsigned short)(offs))
  47. #define BANKNUM(offs)   (((unsigned short *)(&(offs)))[1])
  48. #define BANKLFT(offs)   (0x10000 - BANKPOS(offs))
  49.  
  50. /* dummie Amiga Keys */
  51. #define AK_EjectDisk 0xfe
  52. #define AK_ChangeDisk 0xff
  53.  
  54. /* Command Flags */
  55. #define ResetCPU    0x001
  56. #define EjectDisk0  0x002
  57. #define EjectDisk1  0x004
  58. #define EjectDisk2  0x008
  59. #define EjectDisk3  0x010
  60. #define ChangeDisk0 0x020
  61. #define ChangeDisk1 0x040
  62. #define ChangeDisk2 0x080
  63. #define ChangeDisk3 0x100
  64.  
  65. /* PC Keys */
  66. #define SCODE_CURSORBLOCKUP    103    /* Cursor key block. */
  67. #define SCODE_CURSORBLOCKLEFT 105
  68. #define SCODE_CURSORBLOCKRIGHT 106
  69. #define SCODE_CURSORBLOCKDOWN 108
  70.  
  71. #define SCODE_INSERT 110
  72. #define SCODE_HOME 102
  73. #define SCODE_PGUP 104
  74. #define SCODE_DELETE 111
  75. #define SCODE_END 107
  76. #define SCODE_PGDN 109
  77.  
  78. #define SCODE_KEYPAD0    82
  79. #define SCODE_KEYPAD1    79
  80. #define SCODE_KEYPAD2    80
  81. #define SCODE_KEYPAD3    81
  82. #define SCODE_KEYPAD4    75
  83. #define SCODE_KEYPAD5    76
  84. #define SCODE_KEYPAD6    77
  85. #define SCODE_KEYPAD7    71
  86. #define SCODE_KEYPAD8    72
  87. #define SCODE_KEYPAD9    73
  88. #define SCODE_KEYPADENTER    96
  89. #define SCODE_KEYPADPLUS    78
  90. #define SCODE_KEYPADMINUS    74
  91.  
  92. #define SCODE_Q        16
  93. #define SCODE_W        17
  94. #define SCODE_E        18
  95. #define SCODE_R        19
  96. #define SCODE_T        20
  97. #define SCODE_Y        21
  98. #define SCODE_U        22
  99. #define SCODE_I        23
  100. #define SCODE_O        24
  101. #define SCODE_P        25
  102.  
  103. #define SCODE_A        30
  104. #define SCODE_S        31
  105. #define SCODE_D        32
  106. #define SCODE_F        33
  107. #define SCODE_G        34
  108. #define SCODE_H        35
  109. #define SCODE_J        36
  110. #define SCODE_K        37
  111. #define SCODE_L        38
  112.  
  113. #define SCODE_Z        44
  114. #define SCODE_X        45
  115. #define SCODE_C        46
  116. #define SCODE_V        47
  117. #define SCODE_B        48
  118. #define SCODE_N        49
  119. #define SCODE_M        50
  120.  
  121. #define SCODE_ESCAPE        1
  122. #define SCODE_ENTER        28
  123. #define SCODE_RIGHTCONTROL    97
  124. #define SCODE_CONTROL    97
  125. #define SCODE_RIGHTALT    100
  126. #define SCODE_LEFTCONTROL    29
  127. #define SCODE_LEFTALT    56
  128. #define SCODE_SPACE        57
  129.  
  130. #define SCODE_F1        59
  131. #define SCODE_F2        60
  132. #define SCODE_F3        61
  133. #define SCODE_F4        62
  134. #define SCODE_F5        63
  135. #define SCODE_F6        64
  136. #define SCODE_F7        65
  137. #define SCODE_F8        66
  138. #define SCODE_F9        67
  139. #define SCODE_F10        68
  140.  
  141. #define KEY_EVENTRELEASE 0
  142. #define KEY_EVENTPRESS 1
  143.  
  144. #define SCODE_0 11
  145. #define SCODE_1 2
  146. #define SCODE_2 3
  147. #define SCODE_3 4
  148. #define SCODE_4 5
  149. #define SCODE_5 6
  150. #define SCODE_6 7
  151. #define SCODE_7 8
  152. #define SCODE_8 9
  153. #define SCODE_9 10
  154.  
  155. #define SCODE_LEFTSHIFT 42
  156. #define SCODE_RIGHTSHIFT 54
  157. #define SCODE_TAB 15
  158.  
  159. #define SCODE_F11 87
  160. #define SCODE_F12 88
  161. #define SCODE_NEXT 81
  162. #define SCODE_PRIOR 73
  163. #define SCODE_BS 14
  164. /*
  165. #define SCODE_asciicircum 1
  166. */
  167. #define SCODE_bracketleft 26
  168. #define SCODE_bracketright 27
  169. #define SCODE_comma 51
  170. #define SCODE_period 52
  171. #define SCODE_slash 53
  172. #define SCODE_semicolon 39
  173. #define SCODE_grave 40
  174. #define SCODE_minus 12
  175. #define SCODE_equal 13
  176. #define SCODE_numbersign 41
  177. #define SCODE_ltgt 43
  178. #define SCODE_scrolllock 70
  179.  
  180. #define SCODE_LWIN95 125
  181. #define SCODE_RWIN95 126
  182. #define SCODE_MWIN95 127
  183.  
  184. #define SCODE_Caps_Lock 58
  185.  
  186. static unsigned char escape_keys[128] = {
  187.   0,            0,            0,        0,
  188.   0,             0,            0,        0,
  189.   0,             0,            0,        0,
  190.   0,             0,            0,        0,
  191.   0,             0,            0,        0,
  192.   0,             0,            0,        0,
  193.   0,            0,            0,        0,
  194.   SCODE_KEYPADENTER,    SCODE_RIGHTCONTROL,    0,        0,
  195.   0,             0,            0,        0,
  196.   0,             0,            0,        0,
  197.   0,             0,            0,        0,
  198.   0,             0,            0,        0,
  199.   0,             0,            0,        0,
  200.   0,             0,            0,        0,
  201.   0,             0,            0,        0,
  202.   0,             0,            0,        0,
  203.   0,             0,            0,        0,
  204.   0,            0,             0,        SCODE_HOME,
  205.   SCODE_CURSORBLOCKUP,    SCODE_PGUP,        0,        SCODE_CURSORBLOCKLEFT,
  206.   0,            SCODE_CURSORBLOCKRIGHT,    0,        SCODE_END,
  207.   SCODE_CURSORBLOCKDOWN,SCODE_PGDN,        SCODE_INSERT,    SCODE_DELETE,
  208.   0,            0,            0,        0,
  209.   0,            0,            0,        SCODE_LWIN95,
  210.   SCODE_RWIN95,        SCODE_MWIN95,        0,        0,
  211.   0,            0,            0,        0,
  212.   0,            0,            0,        0,
  213.   0,            0,            0,        0,
  214.   0,            0,            0,        0,
  215.   0,            0,            0,        0,
  216.   0,            0,            0,        0,
  217.   0,            0,            0,        0,
  218.   0,            0,            0,        0
  219. };
  220.  
  221. static int vsize;
  222. static int linebytes;
  223. static int screenheight;
  224. static int screencolors;
  225. static int use_fastline;
  226. static int CommandFlags = 0;
  227.  
  228. xcolnr xcolors[4096];
  229.  
  230. struct vidbuf_description gfxvidinfo;
  231.  
  232. void flush_line(int y)
  233. {
  234.     static char *addr, *ptr;
  235.     int target_y = y, target_x;
  236.     long offs;
  237.     int page, left;
  238.  
  239.     addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
  240.     switch (screen_res) {
  241.      case 0:
  242.     if (CorrectAspectRatio) {
  243.         if (target_y%3==0)
  244.         return;
  245.         target_y=(target_y<<1)/3+5;
  246.     } else
  247.         target_y -= 8;
  248.     addr += gfxvidinfo.pixbytes * (prev_max_diwstop - 328);
  249.     break;
  250.      case 1:
  251.     if (CorrectAspectRatio) {
  252.         if (target_y%5==0)
  253.         return;
  254.         target_y=(target_y<<2)/5+6;
  255.     } else
  256.         target_y -= 8;
  257.     addr += prev_max_diwstop - 328;
  258.     target_y -= 8;
  259.     break;
  260.      case 2:
  261.     if (CorrectAspectRatio) {
  262.         if (target_y%3==0)
  263.         return;
  264.         target_y=(target_y<<1)/3+10;
  265.     } else
  266.         target_y += 57;
  267.     addr += prev_max_diwstop - 328;
  268.     break;
  269.      case 3:
  270.     if (CorrectAspectRatio) {
  271.         if (target_y%5==0)
  272.         return;
  273.         target_y=(target_y<<2)/5+12;
  274.     } else
  275.         target_y += 97;
  276.     addr += gfxvidinfo.pixbytes * (prev_max_diwstop - 656);
  277.     break;
  278.      case 4:
  279.     if (CorrectAspectRatio)
  280.         target_y += 15;
  281.     else
  282.         target_y += 157;
  283.     break;
  284.     }
  285.     if (target_y < screenheight && target_y >= 0) {
  286.     if(use_fastline) {
  287.         offs = target_y * _GrContextInfo.current.gc_lineoffset;
  288.         ptr = &_GrContextInfo.current.gc_baseaddr[0][BANKPOS(offs)];
  289.         page = BANKNUM(offs);
  290.         left = BANKLFT(offs);
  291.         if (page != _GrDriverInfo.curbank) {
  292.         _GrDriverInfo.curbank = page;
  293.         (*_GrDriverInfo.setbank)(page);
  294.         }
  295.         if (left >= linebytes)
  296.         asm ("
  297.              push %%es
  298.              cld
  299.              movw %0, %%es
  300.              shrl $2, %%ecx
  301.              rep
  302.              movsl
  303.              pop %%es
  304.              "
  305.              :
  306.              : "g" (_GrContextInfo.current.gc_selector),
  307.                "S" (addr), "D" (ptr), "c" (linebytes)
  308.              : "%esi", "%edi", "%ecx", "cc"
  309.         );
  310.         else {
  311.         asm ("
  312.              push %%es
  313.              cld
  314.              movw %1, %%es
  315.              shrl $2, %%ecx
  316.              rep
  317.              movsl
  318.              pop %%es
  319.              "
  320.              : "=D" (ptr)
  321.              : "g" (_GrContextInfo.current.gc_selector),
  322.                "S" (addr), "0" (ptr), "c" (left)
  323.              : "%esi", "%edi", "%ecx", "cc"
  324.         );
  325.         ptr = ptr - 0x10000;
  326.         _GrDriverInfo.curbank = page + 1;
  327.         (*_GrDriverInfo.setbank)(_GrDriverInfo.curbank);
  328.         asm ("
  329.              push %%es
  330.              cld
  331.              movw %0, %%es
  332.              addl %1, %%esi
  333.              subl %1, %%ecx
  334.              shrl $2, %%ecx
  335.              rep
  336.              movsl
  337.              pop %%es
  338.              "
  339.              :
  340.              : "g" (_GrContextInfo.current.gc_selector), "g" (left),
  341.                "S" (addr), "D" (ptr), "c" (linebytes)
  342.              : "%esi", "%edi", "%ecx", "cc"
  343.         );
  344.         }
  345.     } else {
  346.         for (target_x=0; target_x<320; target_x++, addr++)
  347.         (*GrCurrentFrameDriver()->drawpixel)(target_x, target_y, *addr);
  348.     }
  349.     }
  350. }
  351.  
  352. void flush_block(int a, int b)
  353. {
  354.     abort();
  355. }
  356.  
  357. void flush_screen(int a, int b)
  358. {
  359. }
  360.  
  361. static int colors_allocated;
  362.  
  363. static int get_color(int r, int g, int b, xcolnr *cnp)
  364. {
  365.     if (colors_allocated == 256)
  366.     return -1;
  367.     *cnp = colors_allocated;
  368.     GrSetColor(colors_allocated, doMask(r, 8, 0), doMask(g, 8, 0), doMask(b, 8, 0));
  369.     colors_allocated++;
  370.     return 1;
  371. }
  372.  
  373. static void init_colors(void)
  374. {
  375.     int rw = 5, gw = 5, bw = 5;
  376.     colors_allocated = 0;
  377.     if (color_mode == 2) gw = 6;
  378.  
  379.     if (gfxvidinfo.pixbytes == 2)
  380.     alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
  381.     else
  382.     alloc_colors256(get_color);
  383. }
  384.  
  385. int buttonstate[3] = { 0, 0, 0 };
  386. int lastmx, lastmy;
  387. int newmousecounters = 0;
  388.  
  389. static int keystate[256];
  390. static int ledsstate;
  391.  
  392. static int scancode2amiga(int scancode)
  393. {
  394.     switch(scancode) {
  395.      case SCODE_A: return AK_A;
  396.      case SCODE_B: return AK_B;
  397.      case SCODE_C: return AK_C;
  398.      case SCODE_D: return AK_D;
  399.      case SCODE_E: return AK_E;
  400.      case SCODE_F: return AK_F;
  401.      case SCODE_G: return AK_G;
  402.      case SCODE_H: return AK_H;
  403.      case SCODE_I: return AK_I;
  404.      case SCODE_J: return AK_J;
  405.      case SCODE_K: return AK_K;
  406.      case SCODE_L: return AK_L;
  407.      case SCODE_M: return AK_M;
  408.      case SCODE_N: return AK_N;
  409.      case SCODE_O: return AK_O;
  410.      case SCODE_P: return AK_P;
  411.      case SCODE_Q: return AK_Q;
  412.      case SCODE_R: return AK_R;
  413.      case SCODE_S: return AK_S;
  414.      case SCODE_T: return AK_T;
  415.      case SCODE_U: return AK_U;
  416.      case SCODE_V: return AK_V;
  417.      case SCODE_W: return AK_W;
  418.      case SCODE_X: return AK_X;
  419.      case SCODE_Y: return AK_Y;
  420.      case SCODE_Z: return AK_Z;
  421.     
  422.      case SCODE_0: return AK_0;
  423.      case SCODE_1: return AK_1;
  424.      case SCODE_2: return AK_2;
  425.      case SCODE_3: return AK_3;
  426.      case SCODE_4: return AK_4;
  427.      case SCODE_5: return AK_5;
  428.      case SCODE_6: return AK_6;
  429.      case SCODE_7: return AK_7;
  430.      case SCODE_8: return AK_8;
  431.      case SCODE_9: return AK_9;
  432.     
  433.      case SCODE_KEYPAD0: return AK_NP0;
  434.      case SCODE_KEYPAD1: return AK_NP1;
  435.      case SCODE_KEYPAD2: return AK_NP2;
  436.      case SCODE_KEYPAD3: return AK_NP3;
  437.      case SCODE_KEYPAD4: return AK_NP4;
  438.      case SCODE_KEYPAD5: return AK_NP5;
  439.      case SCODE_KEYPAD6: return AK_NP6;
  440.      case SCODE_KEYPAD7: return AK_NP7;
  441.      case SCODE_KEYPAD8: return AK_NP8;
  442.      case SCODE_KEYPAD9: return AK_NP9;
  443.     
  444.      case SCODE_F1: return AK_F1;
  445.      case SCODE_F2: return AK_F2;
  446.      case SCODE_F3: return AK_F3;
  447.      case SCODE_F4: return AK_F4;
  448.      case SCODE_F5: return AK_F5;
  449.      case SCODE_F6: return AK_F6;
  450.      case SCODE_F7: return AK_F7;
  451.      case SCODE_F8: return AK_F8;
  452.      case SCODE_F9: return AK_F9;
  453.      case SCODE_F10: return AK_F10;
  454.  
  455.      case SCODE_BS: return AK_BS;
  456.      case SCODE_LEFTCONTROL: return AK_CTRL;
  457.      case SCODE_RIGHTCONTROL: return AK_CTRL;
  458.      case SCODE_TAB: return AK_TAB;
  459.      case SCODE_LEFTALT: return AK_LALT;
  460.      case SCODE_RIGHTALT: return AK_RALT;
  461.      case SCODE_ENTER: return AK_RET;
  462.      case SCODE_SPACE: return AK_SPC;
  463.      case SCODE_LEFTSHIFT: return AK_LSH;
  464.      case SCODE_RIGHTSHIFT: return AK_RSH;
  465.      case SCODE_ESCAPE: return AK_ESC;
  466.     
  467.      case SCODE_INSERT: break;
  468. /*     case SCODE_END:
  469.      case SCODE_HOME: break;*/
  470.  
  471.      case SCODE_DELETE: return AK_DEL;
  472.      case SCODE_CURSORBLOCKUP: return AK_UP;
  473.      case SCODE_CURSORBLOCKDOWN: return AK_DN;
  474.      case SCODE_CURSORBLOCKLEFT: return AK_LF;
  475.      case SCODE_CURSORBLOCKRIGHT: return AK_RT;
  476.  
  477.      case SCODE_F11: return AK_BACKSLASH;
  478. /*
  479.      case SCODE_asciicircum: return AK_00;
  480.  */
  481.      case SCODE_bracketleft: return AK_LBRACKET;
  482.      case SCODE_bracketright: return AK_RBRACKET;
  483.      case SCODE_comma: return AK_COMMA;
  484.      case SCODE_period: return AK_PERIOD;
  485.      case SCODE_slash: return AK_SLASH;
  486.      case SCODE_semicolon: return AK_SEMICOLON;
  487.      case SCODE_grave: return AK_QUOTE;
  488.      case SCODE_minus: return AK_MINUS;
  489.      case SCODE_equal: return AK_EQUAL;
  490.  
  491.     /* This one turns off screen updates. */
  492.      case SCODE_scrolllock: return AK_inhibit;
  493.  
  494.      case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
  495.      case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI;
  496.  
  497. /*#ifdef KBD_LANG_DE*/
  498.      case SCODE_numbersign: return AK_NUMBERSIGN;
  499.      case SCODE_ltgt: return AK_LTGT;
  500. /*#endif*/
  501.      case SCODE_END: return AK_EjectDisk;
  502.      case SCODE_HOME: return AK_ChangeDisk;
  503.     }
  504.     return -1;
  505. }
  506.  
  507. void my_kbd_handler(void)
  508. {
  509.     static is_escape = 0;
  510.     int scancode, newstate, akey;
  511.     scancode = inportb(0x60);
  512.     if (scancode == 0xe0) {
  513.     is_escape = 1;
  514.     outportb(0x20, 0x20);
  515.     return;
  516.     }
  517.     newstate = !(scancode & 0x80);
  518.     scancode = scancode & 0x7f;
  519.     if (is_escape) {
  520.     scancode = escape_keys[scancode];
  521.     is_escape = 0;
  522.     }
  523.     outportb(0x20, 0x20);
  524.  
  525.     akey = scancode2amiga(scancode);
  526.     if (scancode == SCODE_Caps_Lock) {
  527.     if (newstate == KEY_EVENTPRESS) {
  528.         akey = AK_CAPSLOCK;
  529.         newstate = !keystate[akey];
  530.     } else
  531.         return;
  532.     }
  533.     if (scancode == SCODE_F12)
  534.     specialflags |= SPCFLAG_BRK;
  535.  
  536.     if (akey == -1)
  537.     return;
  538.     if (akey <= 0xFF) {
  539.     if (keystate[akey] == newstate)
  540.         return;
  541.     keystate[akey] = newstate;
  542.     }
  543.  
  544.     if ((akey != AK_EjectDisk) && (akey != AK_ChangeDisk)) {
  545.     if (newstate == KEY_EVENTPRESS) {
  546.     if (akey == AK_inhibit)
  547.         inhibit_frame ^= 1;
  548.     else
  549.         record_key (akey << 1);
  550.     } else
  551.     record_key ((akey << 1) | 1);
  552.     }
  553.  
  554.     /* "Affengriff" */
  555.     if (keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
  556.     CommandFlags |= ResetCPU;
  557.     if (keystate[AK_EjectDisk]) {
  558.     if (keystate[AK_F1])
  559.         CommandFlags |= EjectDisk0;
  560.     if (keystate[AK_F2])
  561.         CommandFlags |= EjectDisk1;
  562.     if (keystate[AK_F3])
  563.         CommandFlags |= EjectDisk2;
  564.     if (keystate[AK_F4])
  565.         CommandFlags |= EjectDisk3;
  566.     }
  567.     if (keystate[AK_ChangeDisk]) {
  568.     if (keystate[AK_F1])
  569.         CommandFlags |= ChangeDisk0;
  570.     if (keystate[AK_F2])
  571.         CommandFlags |= ChangeDisk1;
  572.     if (keystate[AK_F3])
  573.         CommandFlags |= ChangeDisk2;
  574.     if (keystate[AK_F4])
  575.         CommandFlags |= ChangeDisk3;
  576.     }
  577. }
  578.  
  579. void my_mouse_handler(_go32_dpmi_registers *mouse_regs)
  580. {
  581.     lastmx = (short)mouse_regs->x.si;
  582.     lastmy = (short)mouse_regs->x.di;
  583.     buttonstate[0] = mouse_regs->x.bx & 1;
  584.     buttonstate[1] = mouse_regs->x.bx & 4;
  585.     buttonstate[2] = mouse_regs->x.bx & 2;
  586. }
  587.  
  588. _go32_dpmi_seginfo old_kbd_handler, new_kbd_handler, mouse_handler;
  589. _go32_dpmi_registers mouse_callback_regs;
  590.  
  591. int graphics_init(void)
  592. {
  593.     int i;
  594.     GrFrameMode fm;
  595.     const GrVideoMode *mp;
  596.     int found_mode = 0;
  597.     int gw, gh, gc, gbpp;
  598.     _go32_dpmi_registers regs;
  599.  
  600.     remove("uae.log");
  601.     _go32_want_ctrl_break(1);
  602.     __djgpp_set_ctrl_c(0);
  603.  
  604.     if(ersatzkickfile && disk_empty(0)) {
  605.     fprintf (stderr, "No KickStart and no bootdisk, giving up.\n");
  606.     return 0;
  607.     }
  608.  
  609.     _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_kbd_handler);
  610.     new_kbd_handler.pm_offset = (int)my_kbd_handler;
  611.     if (_go32_dpmi_allocate_iret_wrapper(&new_kbd_handler) != 0) {
  612.     fprintf (stderr, "Can't allocate keyboard iret_wrapper.\n");
  613.     return 0;
  614.     }
  615.     if (_go32_dpmi_set_protected_mode_interrupt_vector(9, &new_kbd_handler) != 0) {
  616.     fprintf (stderr, "Can't set protected mode interrupt vector.\n");
  617.     return 0;
  618.     }
  619.  
  620.     regs.x.ax=0;
  621.     regs.x.ss=regs.x.sp=regs.x.flags=0;
  622.     _go32_dpmi_simulate_int(0x33, ®s);
  623.     if (regs.x.ax==0) {
  624.     fprintf (stderr, "Mouse driver not present.\n");
  625.     return 0;
  626.     }
  627.     mouse_handler.pm_offset = (int)my_mouse_handler;
  628.     if (_go32_dpmi_allocate_real_mode_callback_retf(&mouse_handler, &mouse_callback_regs) != 0) {
  629.     fprintf (stderr, "Can't allocate mouse callback_retf.\n");
  630.     return 0;
  631.     }
  632.     regs.x.ax=0xc;
  633.     regs.x.cx=0x7f;
  634.     regs.x.es=mouse_handler.rm_segment;
  635.     regs.x.dx=mouse_handler.rm_offset;
  636.     regs.x.ss=regs.x.sp=regs.x.flags=0;
  637.     _go32_dpmi_simulate_int(0x33, ®s);
  638.  
  639.     switch (screen_res) {
  640.      case 0: gw=320; gh=200; use_fastline=1; break;
  641.      case 1: gw=320; gh=240; use_fastline=0; break;
  642.      case 2: gw=320; gh=400; use_fastline=0; break;
  643.      case 3: gw=640; gh=480; use_fastline=1; break;
  644.      case 4: gw=800; gh=600; use_fastline=1; break;
  645.      default:
  646.     fprintf(stderr, "Invalid screen mode.\n");
  647.     return 0;
  648.     }
  649.     if (CorrectAspectRatio && (screen_res>1))
  650.     dont_want_aspect=0;
  651.     else
  652.     dont_want_aspect=1;
  653.     switch (color_mode) {
  654.      case 0: gc=256; gbpp=8; break;
  655.      case 1: gc=32768; gbpp=16; break;
  656.      case 2: gc=65536; gbpp=16; break;
  657.      default:
  658.     fprintf(stderr, "Invalid color mode.\n");
  659.     return 0;
  660.     }
  661.     GrSetDriver(NULL);
  662.     if (GrCurrentVideoDriver() == NULL) {
  663.     _GrDriverInfo.vdriver = NULL;
  664.     fprintf(stderr, "Graphics adapter not supported.\n");
  665.     return 0;
  666.     }
  667.     for (fm = GR_frameHERC1; (fm <= GR_frameSVGA32H) && (!found_mode); fm++) {
  668.     for (mp = GrFirstVideoMode(fm); mp && (!found_mode); mp = GrNextVideoMode(mp)) {
  669.         if (gw==mp->width && gh==mp->height && gbpp==mp->bpp)
  670.         found_mode = 1;
  671.     }
  672.     }
  673.     if (!found_mode) {
  674.     _GrDriverInfo.vdriver = NULL;
  675.     fprintf(stderr, "Sorry, this combination of color and video mode is not available.\n");
  676.     return 0;
  677.     }
  678.     if (GrSetMode(GR_width_height_color_graphics, gw, gh, gc) == 0) {
  679.     _GrDriverInfo.vdriver = NULL;
  680.     fprintf(stderr, "Graphics inicialization error.\n");
  681.     return 0;
  682.     }
  683.     freopen("UAE.LOG", "w", stderr);
  684.  
  685.     gfxvidinfo.pixbytes = (gbpp >> 3);
  686.     vsize = dont_want_aspect ? numscrlines : 2*numscrlines;
  687.     gfxvidinfo.maxblocklines = 0;
  688.     gfxvidinfo.rowbytes = 800 * gfxvidinfo.pixbytes;
  689.     gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize);
  690.     memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize);
  691.  
  692.     linebytes = gw * gfxvidinfo.pixbytes;
  693.     screenheight = gh;
  694.     screencolors = gc;
  695.  
  696.     init_colors();
  697.  
  698.     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
  699.     for(i = 0; i < 256; i++)
  700.     keystate[i] = 0;
  701.  
  702.     lastmx = lastmy = 0;
  703.     newmousecounters = 0;
  704.  
  705.     return 1;
  706. }
  707.  
  708. void graphics_leave(void)
  709. {
  710.     _go32_dpmi_registers regs;
  711.  
  712.     if (_GrDriverInfo.vdriver) {
  713.     _GrDriverInfo.vdriver->reset();
  714.     _GrDriverInfo.vdriver = NULL;
  715.     }
  716.     freopen("CON", "w", stderr);
  717.     _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_kbd_handler);
  718.     _go32_dpmi_free_iret_wrapper(&new_kbd_handler);
  719.     regs.x.ax=0xc;
  720.     regs.x.cx=0x0;
  721.     regs.x.ss=regs.x.sp=regs.x.flags=0;
  722.     _go32_dpmi_simulate_int(0x33, ®s);
  723.     _go32_dpmi_free_real_mode_callback(&mouse_handler);
  724. }
  725.  
  726. void handle_events(void)
  727. {
  728.     if (CommandFlags) {
  729.     if (CommandFlags & ResetCPU) {
  730.         MC68000_reset();
  731.         CommandFlags &= ~ResetCPU;
  732.     }
  733.     if (CommandFlags & EjectDisk0) {
  734.         disk_eject(0);
  735.         CommandFlags &= ~EjectDisk0;
  736.     }
  737.     if (CommandFlags & EjectDisk1) {
  738.         disk_eject(1);
  739.         CommandFlags &= ~EjectDisk1;
  740.     }
  741.     if (CommandFlags & EjectDisk2) {
  742.         disk_eject(2);
  743.         CommandFlags &= ~EjectDisk2;
  744.     }
  745.     if (CommandFlags & EjectDisk3) {
  746.         disk_eject(3);
  747.         CommandFlags &= ~EjectDisk3;
  748.     }
  749.     if (CommandFlags & ChangeDisk0) {
  750.         HandleDisk(0);
  751.         keystate[AK_ChangeDisk] = 0;
  752.         keystate[AK_F1] = 0;
  753.         record_key ((AK_F1 << 1) | 1);
  754.         CommandFlags &= ~ChangeDisk0;
  755.     }
  756.     if (CommandFlags & ChangeDisk1) {
  757.         HandleDisk(1);
  758.         keystate[AK_ChangeDisk] = 0;
  759.         keystate[AK_F2] = 0;
  760.         record_key ((AK_F2 << 1) | 1);
  761.         CommandFlags &= ~ChangeDisk1;
  762.     }
  763.     if (CommandFlags & ChangeDisk2) {
  764.         HandleDisk(2);
  765.         keystate[AK_ChangeDisk] = 0;
  766.         keystate[AK_F3] = 0;
  767.         record_key ((AK_F3 << 1) | 1);
  768.         CommandFlags &= ~ChangeDisk2;
  769.     }
  770.     if (CommandFlags & ChangeDisk3) {
  771.         HandleDisk(3);
  772.         keystate[AK_ChangeDisk] = 0;
  773.         keystate[AK_F4] = 0;
  774.         record_key ((AK_F4 << 1) | 1);
  775.         CommandFlags &= ~ChangeDisk3;
  776.     }
  777.     }
  778. }
  779.  
  780. int debuggable(void)
  781. {
  782.     return 0;
  783. }
  784.  
  785. int needmousehack(void)
  786. {
  787.     return 0;
  788. }
  789.  
  790. void LED(int on)
  791. {
  792. }
  793.  
  794. void HandleDisk(int num) {
  795.     int i;
  796.     char buf[256];
  797.     _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_kbd_handler);
  798.     GrSetMode(GR_80_25_text);
  799.     switch(num) {
  800.     case 0:
  801.         puts("Enter filename for drive DF0:");
  802.         break;
  803.     case 1:
  804.         puts("Enter filename for drive DF1:");
  805.         break;
  806.     case 2:
  807.         puts("Enter filename for drive DF2:");
  808.         break;
  809.     case 3:
  810.         puts("Enter filename for drive DF3:");
  811.         break;
  812.     }
  813.     gets(buf);
  814.     disk_insert(num, buf);
  815.     _go32_dpmi_set_protected_mode_interrupt_vector(9, &new_kbd_handler);
  816.     /* Restore screen */
  817.     GrSetMode(GR_width_height_color_graphics, linebytes / gfxvidinfo.pixbytes, screenheight, screencolors);
  818.     if (gfxvidinfo.pixbytes == 1) {
  819.     colors_allocated = 0;
  820.     alloc_colors256(get_color);
  821.     }
  822.     for(i=0; i<vsize; i++)
  823.     flush_line(i);
  824. }
  825.